package com.gitee.huanminabc.jcommon.container;

import lombok.Data;

import java.io.Serializable;
import java.util.List;

/**
 * 数据分页
 *
 * @param <T>
 * @author 胡安民
 */

@Data
public class DataPage<T> implements Serializable {

    // 页数（第几页）
    private int currentpage;

    // 查询数据库里面对应的数据有多少条
    private int total;// 从数据库查处的总记录数

    // 每页查几条
    private int size;

    // 下页
    private int next;

    //当前页的 数据
    private List<T> data;

    // 最后一页
    private int last;

    //起点
    private int lpage;
    //终点
    private int rpage;

    //从哪条开始查
    private int start;


    final private int offsize = 2;  // 固定别动

    public DataPage() {
        super();
    }

    /****
     *
     * @param currentpage  当前页
     * @param total  总页数
     * @param pagesize   每页显示多少条
     */
    public void setCurrentPage(int currentpage, int total, int pagesize) {

        //如果整除表示正好分N页，如果不能整除在N页的基础上+1页
        int totalPages = (total % pagesize == 0 ? total / pagesize : (total / pagesize) + 1);

        //总页数
        this.last = totalPages;

        //判断当前页是否越界,如果越界，我们就查最后一页
        this.currentpage = Math.min(currentpage, totalPages);
        //判断当前页是否小于1 如果小于那么就是1
        if (currentpage < 1) {
            this.currentpage = 1;
        }

        //计算start
        this.start = (this.currentpage - 1) * pagesize;
    }

    //上一页
    public long getUpper() {
        return currentpage > 1 ? currentpage - 1 : currentpage;
    }

    //总共有多少页，即末页
    public void setLast(int last) {
        this.last = total % size == 0 ? total / size : (total / size) + 1;
    }


    /****
     * 数据库分页  ,求出分页后的信息
     * @param total   总记录数
     * @param currentPage    当前页
     * @param pageSize    每页显示多少条
     */
    public DataPage(int total, int currentPage, int pageSize) {
        initPage(total, currentPage, pageSize);
    }

    /**
     * 传入全部数据自动分页
     *
     * @param currentPage 当前页
     * @param pageSize    每页显示多少条
     * @param data        数据库查询的全部数据
     */
    public DataPage(int currentPage, int pageSize, List<T> data) {
        initPage(data, currentPage, pageSize);
    }
    public DataPage(int total, int currentPage, int pageSize, List<T> currentPageData) {
        initPage(total, currentPage, pageSize);
        this.data = currentPageData;
    }

    /****
     * 初始化分页  偏移量方式
     * @param total 总记录数
     * @param currentPage 当前页
     * @param pageSize 每页显示多少条
     */
    public void initPage(int total, int currentPage, int pageSize) {
        //总记录数
        this.total = total;
        //每页显示多少条
        this.size = pageSize;

        //计算当前页和数据库查询起始值以及总页数
        setCurrentPage(currentPage, total, pageSize);

        //分页计算
        //需要向上一页执行多少次
        this.lpage = currentPage - this.offsize;            //正常情况下的起点
        this.rpage = currentPage + this.offsize;        //正常情况下的终点

        //页差=总页数和结束页的差
        int topdiv = this.last - rpage;                //判断是否大于最大页数

        /*
         * 起点页
         * 1、页差<0  起点页=起点页+页差值
         * 2、页差>=0 起点和终点判断
         */
        this.lpage = topdiv < 0 ? this.lpage + topdiv : this.lpage;

        /*
          结束页
          1、起点页<=0   结束页=|起点页|+1
          2、起点页>0    结束页
         */
        this.rpage = this.lpage <= 0 ? this.rpage + (this.lpage * -1) + 1 : this.rpage;

        /*
         * 当起点页<=0  让起点页为第一页
         * 否则不管
         */
        this.lpage = this.lpage <= 0 ? 1 : this.lpage;

        /*
         * 如果结束页>总页数   结束页=总页数
         * 否则不管
         */
        this.rpage = Math.min(this.rpage, last);
    }

    public void initPage(List<T> list, int currentPage, int pageSize) {
        //总记录数
        this.total = list.size();
        //每页显示多少条
        this.size = pageSize;

        //计算当前页和数据库查询起始值以及总页数
        setCurrentPage(currentPage, total, pageSize);

        //分页计算   进行偏移 页数
        this.lpage = currentPage - this.offsize;            //正常情况下的起点
        this.rpage = currentPage + this.offsize;        //正常情况下的终点

        //页差=总页数和结束页的差
        int topdiv = this.last - rpage;                //判断是否大于最大页数

        /*
         * 起点页
         * 1、页差<0  起点页=起点页+页差值
         * 2、页差>=0 起点和终点判断
         */
        this.lpage = topdiv < 0 ? this.lpage + topdiv : this.lpage;

        /*
         * 结束页
         * 1、起点页<=0   结束页=|起点页|+1
         * 2、起点页>0    结束页
         */
        this.rpage = this.lpage <= 0 ? this.rpage + (this.lpage * -1) + 1 : this.rpage;

        /*
         * 当起点页<=0  让起点页为第一页
         * 否则不管
         */
        this.lpage = this.lpage <= 0 ? 1 : this.lpage;

        /*
         * 如果结束页>总页数   结束页=总页数
         * 否则不管
         */
        this.rpage = Math.min(this.rpage, last);
        List<T> list1;
        if (this.currentpage <= 1) {
            if (this.total >= pageSize) {  //总条数如果大于或者等于每页显示多少条那么进行切割
                list1 = list.subList(0, this.size);
            } else {
                list1 = list;
            }
        } else {

            if (this.currentpage == this.last || this.currentpage > this.last) {
                this.currentpage = this.last;
                int l = this.currentpage * this.size;
                list1 = list.subList(l - this.size, this.total);
            } else {
                int l = (this.currentpage - 1) * this.size;
                list1 = list.subList(l, l + this.size);
            }

        }

        this.data = list1;

    }


    public long getNext() {
        return currentpage < last ? currentpage + 1 : last;
    }
}
